﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LevelEditor.Objects;
using LevelEditor.Objects.Waypoints;
using LevelEditor.Objects.Tiles;
using LevelEditor.Dao;
using DialogsEditor;
using System.Drawing;

namespace LevelEditor.App.Serialization
{
    class UtilSerialization
    {
        public static readonly List<WaypointsCollection> allWaypointsCollections = new List<WaypointsCollection>();

        public static Character ConvertToCharacter(SCharacter sCharacter, LevelEditor ed)
        {
            Character c = new Character(ed);
            c.Name = sCharacter.Name;
            c.Location = new Point(sCharacter.PositionX, sCharacter.PositionY);
            c.FieldOfView = sCharacter.FieldOfView;
            c.WalkSpeed = sCharacter.WalkSpeed;
            c.PerceptionArea = sCharacter.PerceptionArea;
            c.MyTrigger = ConvertToTriggers(sCharacter.myTriggers, true);
            c.Image = Util.Util.Base64ToImage(sCharacter.ImageInfo);
            c.ID = sCharacter.ID;

            return c;
        }

        public static Item ConvertToItem(SItem sItem, LevelEditor ed)
        {
            Item c = new Item(ed);
            c.Name = sItem.Name;
            c.Location = new Point(sItem.PositionX, sItem.PositionY);
            c.Image = Util.Util.Base64ToImage(sItem.ImageInfo);
            c.MyTrigger = ConvertToTriggers(sItem.myTriggers, false);
            c.ID = sItem.ID;

            return c;
        }

        public static Door ConvertToDoor(SDoor sDoor, LevelEditor ed)
        {
            Door c = new Door(ed);
            c.Name = sDoor.Name;
            c.NameRoom = sDoor.NameRoom;
            c.LoadNextPartLevel = sDoor.LoadNextPartLevel;
            c.IsOpen = Boolean.Parse(sDoor.IsOpen);
            c.IsClosedForever = Boolean.Parse(sDoor.IsClosedForever);
            c.IsBlocked = Boolean.Parse(sDoor.IsBlocked);
            c.Location = new Point(sDoor.PositionX, sDoor.PositionY);
            c.Image = Util.Util.Base64ToImage(sDoor.ImageInfo);
            c.ID = sDoor.ID;

            return c;
        }


        public static List<Trigger> ConvertToTriggers(List<STrigger> list, bool isChar)
        {
            List<Trigger> result = new List<Trigger>();

            foreach (STrigger sTrigger in list)
            {
                Trigger trig = new Trigger();
                trig.ID = sTrigger.Id;
                trig.Name = sTrigger.NameTrigger;
                trig.MappedBehavior = LevelEditorDAO.GetInstance().getBehavior(sTrigger.MappedBehavior.Id);
                if (trig.MappedBehavior != null && isChar)
                    trig.MappedBehavior.Waypoints = ConvertToWaypointsCollection(sTrigger.MappedBehavior.Waypoints);
                else
                    trig.MappedBehavior.Waypoints = new WaypointsCollection();
                //trig.MappedBehavior = ConvertToBehavior(sTrigger.MappedBehavior);

                result.Add(trig);
            }

            return result;
        }

        public static DialogEntity ConvertToDialog(SDialog sDialog)
        {
            DialogEntity dialog = new DialogEntity();

            dialog.SetID(sDialog.Id);
            dialog.title.Text = sDialog.Title;
            dialog.trigger.Text = sDialog.Trigger;
            dialog.charac.Text = sDialog.Character;
            dialog.text.Text = sDialog.Text;
            dialog.idNextDialog = sDialog.IdNextDialog;
            dialog.TitleNextDialog = sDialog.TitleNextDialog;
            dialog.IsProject = Boolean.Parse(sDialog.IsProject);
            dialog.idProject = sDialog.IdProject;
            if (sDialog.Location != null)
                dialog.Location = new Point(sDialog.Location.X, sDialog.Location.Y);

            return dialog;
        }

        public static Behavior ConvertToBehavior(SBehavior sBehavior)
        {
            Behavior behavior = new Behavior();
            behavior.ID = sBehavior.Id;
            behavior.Name = sBehavior.NameBehavior;
            behavior.IsWalk = Boolean.Parse(sBehavior.IsWalk);
            behavior.Images = new List<System.Drawing.Image>();
            behavior.DurationTime = sBehavior.DurationTime;

            foreach (string img in sBehavior.images)
            {
                behavior.Images.Add(Util.Util.Base64ToImage(img));
            }
            behavior.IdProjDialog = sBehavior.IdProjDialog;
            if (sBehavior.Waypoints != null)
                behavior.Waypoints = ConvertToWaypointsCollection(sBehavior.Waypoints);


            return behavior;
        }

        public static WaypointsCollection ConvertToWaypointsCollection(SWaypointCollection sWaypointsCollection)
        {
            WaypointsCollection wayColl = new WaypointsCollection();

            foreach (SWaypoint sWay in sWaypointsCollection.listWaypoints)
            {
                wayColl.Add(ConvertToWaypoint(sWay));
            }
            wayColl.Name = sWaypointsCollection.Name;
            wayColl.IdFinalBehavior = sWaypointsCollection.IdFinalBehavior;
            //wayColl.FinalBehavior = ConvertToBehavior(sWaypointsCollection.FinalBehavior);
            wayColl.Dialog = ConvertToDialog(sWaypointsCollection.DialogEntity);

            SettingWaypointList(wayColl);
            allWaypointsCollections.Add(wayColl);

            return wayColl;
        }

        public static Waypoint ConvertToWaypoint(SWaypoint sWaypoint)
        {
            Waypoint waypoint = new Waypoint();

            waypoint.location = new Point(sWaypoint.Location.X, sWaypoint.Location.Y);
            waypoint.col = sWaypoint.Col;
            waypoint.id = sWaypoint.ID;
            waypoint.row = sWaypoint.Row;

            waypoint.idCollection = sWaypoint.IdCollection;

            waypoint.idNext = sWaypoint.IdNextWaypoint;
            waypoint.idPrevious = sWaypoint.IdPreviousWaypoint;

            waypoint.idCharacter = sWaypoint.IdCharacter;

            //waypoint.next = ConvertToWaypoint(sWaypoint.NextWaypoint);
            //waypoint.previous = ConvertToWaypoint(sWaypoint.PreviousWaypoint);
            //waypoint.character = 

            return waypoint;
        }

        public static void SettingWaypointList(WaypointsCollection w)
        {
            /*Waypoint way = w.Find(
                delegate(Waypoint waypoint)
                {
                    return waypoint.id == way.idNext;
                });*/

            foreach (Waypoint way1 in w)
            {
                Waypoint way = w.Find(delegate(Waypoint waypoint) { return (waypoint.id == way1.idNext && waypoint.idCollection == way1.idCollection); });
                if (way != null)
                {
                    way1.next = way;
                }

                way = w.Find(delegate(Waypoint waypoint) { return (waypoint.id == way1.idPrevious && waypoint.idCollection == way1.idCollection); });
                if (way != null)
                {
                    way1.previous = way;
                }
            }

        }
    }
}
